package com.funsport.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.PostConstruct;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * 微信内容安全检测服务
 * 使用微信官方内容安全API
 *
 * @author Fun-Sport Team
 */
@Slf4j
@Service
public class WechatSecurityService {

    @Value("${wechat.mini-program.app-id}")
    private String appId;

    @Value("${wechat.mini-program.app-secret}")
    private String appSecret;

    private final RestTemplate restTemplate = new RestTemplate();

    /**
     * Access Token缓存
     */
    private String cachedAccessToken;
    private long tokenExpiresAt = 0;

    /**
     * 获取Access Token
     */
    private String getAccessToken() {
        // 如果token还没过期，直接返回
        if (cachedAccessToken != null && System.currentTimeMillis() < tokenExpiresAt) {
            return cachedAccessToken;
        }

        // 获取新的token
        String url = String.format(
            "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s",
            appId, appSecret
        );

        try {
            String response = restTemplate.getForObject(url, String.class);
            JSONObject result = JSON.parseObject(response);

            if (result.containsKey("access_token")) {
                cachedAccessToken = result.getString("access_token");
                int expiresIn = result.getIntValue("expires_in");
                // 提前5分钟过期，避免边界情况
                tokenExpiresAt = System.currentTimeMillis() + (expiresIn - 300) * 1000L;
                log.info("获取Access Token成功，有效期: {}秒", expiresIn);
                return cachedAccessToken;
            } else {
                log.error("获取Access Token失败: {}", response);
                throw new RuntimeException("获取Access Token失败: " + result.getString("errmsg"));
            }
        } catch (Exception e) {
            log.error("获取Access Token异常", e);
            throw new RuntimeException("获取Access Token异常", e);
        }
    }

    /**
     * 检测文本内容是否包含违规信息
     *
     * @param content 待检测的文本内容
     * @param openid  用户的openid（可选）
     * @return true-内容安全，false-内容违规
     */
    public boolean checkText(String content, String openid) {
        if (content == null || content.trim().isEmpty()) {
            return true;
        }

        String accessToken = getAccessToken();
        String url = "https://api.weixin.qq.com/wxa/msg_sec_check?access_token=" + accessToken;

        try {
            // 构建请求参数
            Map<String, Object> params = new HashMap<>();
            params.put("content", content);
            params.put("version", 2); // 使用v2版本
            params.put("scene", 2);   // 场景值: 1资料 2评论 3论坛 4社交日志
            params.put("openid", openid != null ? openid : "");

            // 发送POST请求
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            HttpEntity<String> entity = new HttpEntity<>(JSON.toJSONString(params), headers);

            ResponseEntity<String> response = restTemplate.postForEntity(url, entity, String.class);
            JSONObject result = JSON.parseObject(response.getBody());

            log.debug("文本检测结果: {}", result);

            // errcode: 0正常，87014内容含有违法违规内容
            int errcode = result.getIntValue("errcode");
            
            if (errcode == 0) {
                // 检查result字段
                JSONObject resultData = result.getJSONObject("result");
                if (resultData != null) {
                    String suggest = resultData.getString("suggest");
                    // suggest: pass(正常), risky(风险), review(需人工审核)
                    if ("pass".equals(suggest)) {
                        return true;
                    } else {
                        log.warn("文本检测不通过, suggest: {}, label: {}", 
                            suggest, resultData.getInteger("label"));
                        return false;
                    }
                }
                return true;
            } else if (errcode == 87014) {
                log.warn("文本包含违规内容: {}", content.substring(0, Math.min(50, content.length())));
                return false;
            } else {
                log.error("文本检测接口返回错误: errcode={}, errmsg={}", 
                    errcode, result.getString("errmsg"));
                // 接口异常时，为了不影响用户体验，放行内容
                return true;
            }

        } catch (Exception e) {
            log.error("调用文本检测接口异常", e);
            // 异常时放行，避免影响正常业务
            return true;
        }
    }

    /**
     * 检测文本内容（无openid版本）
     */
    public boolean checkText(String content) {
        return checkText(content, null);
    }

    /**
     * 检测图片内容是否包含违规信息
     *
     * @param imageFile 图片文件
     * @return true-图片安全，false-图片违规
     */
    public boolean checkImage(MultipartFile imageFile) {
        if (imageFile == null || imageFile.isEmpty()) {
            return true;
        }

        try {
            byte[] imageBytes = imageFile.getBytes();
            return checkImage(imageBytes);
        } catch (IOException e) {
            log.error("读取图片文件失败", e);
            return true;
        }
    }

    /**
     * 检测图片内容（字节数组版本）
     *
     * @param imageBytes 图片字节数组
     * @return true-图片安全，false-图片违规
     */
    public boolean checkImage(byte[] imageBytes) {
        if (imageBytes == null || imageBytes.length == 0) {
            return true;
        }

        String accessToken = getAccessToken();
        String url = "https://api.weixin.qq.com/wxa/img_sec_check?access_token=" + accessToken;

        try {
            // 构建multipart请求
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.MULTIPART_FORM_DATA);

            // 创建临时文件资源
            org.springframework.core.io.ByteArrayResource resource = 
                new org.springframework.core.io.ByteArrayResource(imageBytes) {
                    @Override
                    public String getFilename() {
                        return "image.jpg";
                    }
                };

            org.springframework.util.MultiValueMap<String, Object> body = 
                new org.springframework.util.LinkedMultiValueMap<>();
            body.add("media", resource);

            HttpEntity<org.springframework.util.MultiValueMap<String, Object>> entity = 
                new HttpEntity<>(body, headers);

            ResponseEntity<String> response = restTemplate.postForEntity(url, entity, String.class);
            JSONObject result = JSON.parseObject(response.getBody());

            log.debug("图片检测结果: {}", result);

            int errcode = result.getIntValue("errcode");
            
            if (errcode == 0) {
                return true;
            } else if (errcode == 87014) {
                log.warn("图片包含违规内容");
                return false;
            } else {
                log.error("图片检测接口返回错误: errcode={}, errmsg={}", 
                    errcode, result.getString("errmsg"));
                // 接口异常时放行
                return true;
            }

        } catch (Exception e) {
            log.error("调用图片检测接口异常", e);
            // 异常时放行
            return true;
        }
    }

    /**
     * 检测图片URL内容
     *
     * @param imageUrl 图片URL
     * @return true-图片安全，false-图片违规
     */
    public boolean checkImageByUrl(String imageUrl) {
        if (imageUrl == null || imageUrl.trim().isEmpty()) {
            return true;
        }

        try {
            // 下载图片
            ResponseEntity<byte[]> response = restTemplate.getForEntity(imageUrl, byte[].class);
            if (response.getStatusCode() == HttpStatus.OK && response.getBody() != null) {
                return checkImage(response.getBody());
            }
            return true;
        } catch (Exception e) {
            log.error("下载图片失败: {}", imageUrl, e);
            return true;
        }
    }

    /**
     * 批量检测多张图片
     *
     * @param imageUrls 图片URL列表
     * @return true-全部安全，false-存在违规
     */
    public boolean checkImages(String[] imageUrls) {
        if (imageUrls == null || imageUrls.length == 0) {
            return true;
        }

        for (String imageUrl : imageUrls) {
            if (!checkImageByUrl(imageUrl)) {
                return false;
            }
        }
        return true;
    }

    /**
     * 初始化时预热access token
     */
    @PostConstruct
    public void init() {
        try {
            log.info("初始化微信内容安全服务...");
            getAccessToken();
            log.info("微信内容安全服务初始化完成");
        } catch (Exception e) {
            log.error("初始化微信内容安全服务失败", e);
        }
    }
}

